﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using common4gp;
using System.Windows.Input;
using wpf4gp.Helpers;
using System.Windows.Threading;
using wpf4gp.Views;

namespace wpf4gp.ViewModels
{

    /// <summary>
    /// Message box for an <see cref="System.Exception"/>
    /// </summary>
    public class ExceptionMessageBoxViewModel : BaseWindowViewModel
    {

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="ex"><see cref="System.Exception"/> to show</param>
        /// <param name="message">The message to show (if not passed, will see the exception message)</param>
        /// <param name="title">Title of the window</param>
        /// <param name="canViewDetails">False if the user can't see the detail of the Exception</param>
        public ExceptionMessageBoxViewModel(Exception ex, 
                                            string message = null, 
                                            string title = null, 
                                            bool canViewDetails = true)
        {
            Contract.Requires<ArgumentNullException>(ex != null);
            MainException = ex;
            if (message.IsNotNull())
            {
                Message = message;
            }
            else
            {
                Message = ex.Message;
            }
            if (title.IsNotNull())
            {
                Title = title;
            }
            else
            {
                Title = Properties.Resources.ExceptionMessageBox_Title;
            }
            CanViewDetails = canViewDetails;
        }

        /// <summary>
        /// Exception to show
        /// </summary>
        private Exception MainException { get; set; }


        #region Message

        private string _message = null;

        /// <summary>
        /// The message to show
        /// </summary>
        public string Message
        {
            get
            {
                return _message;
            }
            set
            {
                if (_message != value)
                {
                    _message = value;
                    RaisePropertyChanged(() => Message);
                }
            }
        }


        #endregion


        #region Title

        private string _title = null;

        /// <summary>
        /// Title of the window
        /// </summary>
        public string Title
        {
            get
            {
                return _title;
            }
            set
            {
                if (_title != value)
                {
                    _title = value;
                    RaisePropertyChanged(() => Title);
                }
            }
        }

        #endregion


        #region Can view details

        private bool _canViewDetails = true;

        /// <summary>
        /// True if the user can view the detail of the exception
        /// </summary>
        public bool CanViewDetails
        {
            get
            {
                return _canViewDetails;
            }
            set
            {
                if (_canViewDetails != value)
                {
                    _canViewDetails = value;
                    RaisePropertyChanged(() => CanViewDetails);
                }
            }
        }


        #endregion



        #region Show details


        /// <summary>
        /// Command for see the details
        /// </summary>
        public ICommand DetailsCommand
        {
            get
            {
                return new DelegateCommand(ShowDetails, () => CanViewDetails);
            }
        }

        /// <summary>
        /// Show the exception details
        /// </summary>
        private void ShowDetails()
        {
            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() =>
            {
                MainException.ShowDetails();
            }));
        }


        #endregion


        #region Exit


        /// <summary>
        /// Close the window
        /// </summary>
        public ICommand CloseCommand
        {
            get
            {
                return new DelegateCommand(() => DialogResult = true);
            }
        }

        #endregion
    }
}
